#ifndef FASYS_LIBS_SUBSCRIBER_SUBSCRIBER_MANAGER_HPP
#define FASYS_LIBS_SUBSCRIBER_SUBSCRIBER_MANAGER_HPP

#include "types.hpp"
#include "message.hpp"
#include "ichannel_observer.hpp"
#include "ichannels.hpp"
#include "isubscriptions.hpp"
#include "subscription_channel.hpp"
#include <list>
#include <map>
#include <boost/random.hpp>
#include <boost/uuid/uuid_generators.hpp>

namespace fasys{

class subscription;
class channels_container;
class subscription_container;
class subscribe_channel_container;
class isubscriber;


class subscriber_manager
  : public ichannel_observer
  , public isubscriptions
{
public:
  typedef isubscriptions::channel_list channel_list;
  ~subscriber_manager();
  subscriber_manager();

  // проверяет есть ли сообщения в подписке
  virtual bool has_messages(const std::string& key, const std::string& uuid);
  virtual void move_messages(const std::string& key, const std::string& uuid, std::list<message>& ml );
  // вызывать только полсе того, как выгребуться все сообщения из подписки 
  virtual void subscribe( const std::string& key, const std::string& uuid, isubscriber*);
  virtual void describe( const std::string& key, const std::string& uuid, isubscriber*);
  void describe(isubscriber*);

  virtual void publish(const message& m);
  virtual std::string create( const std::string& key, time_t lifetime,  const channel_list& cl);
  /*
  void create_subscription(create_subscription_request& request, create_subscription_response& response);

  void publish(const message_notify& cmd);
  void publish(const message_list_response& cmd);
  */

  void set_channels(ichannels* icm) { _channels_manager = icm; }
private:
  typedef std::map<subscribe_id_t, subscription*> subscription_map;
  subscription_map _subscription_map;
  boost::mt19937 _ran;
  boost::uuids::basic_random_generator<boost::mt19937> _gen;
  subscription_container* _subscriptions;
  channels_container *_channels_container;
  subscribe_id_t _subscription_couner;
  subscribe_channel_container* _channels;
  ichannels* _channels_manager;
};

}

#endif
